#! /usr/local/bin/python
"""
Author: Andy Nagels
Date: 2010-02-26
Valhalladb: Get character info of Valhalla clanmembers from valhalladb.txt.

Copyright (C) 2010 Andy Nagels

This file is part of Valhalladb.

Valhalladb is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Valhalladb is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Valhalladb. If not, see <http://www.gnu.org/licenses/>.
					
"""

import sys, getopt, ConfigParser, time, datetime, os#, psycopg2 as dbapi2
from subprocess import call
from string import strip


class Valhalladb:
 
    def get_pprog(self):
        """ pprog """
        return self._pprog
    
    def set_pprog(self, name):
        """ set pprog """
        self._pprog = name
    
    pprog = property(get_pprog, set_pprog)
    
    def get_pversion(self):
        """ pversion """
        return self._pversion
    
    def set_pversion(self, version):
        """ set pversion """
        self._pversion = version
    
    pversion = property(get_pversion, set_pversion)
     
    def get_prelease(self):
        """ prelease """
        return self._prelease
    
    def set_prelease(self, release):
        """ set prelease """
        self._prelease = release
    
    prelease = property(get_prelease, set_prelease)
     
    def get_pdate(self):
        """ pdate """
        return self._pdate
    
    def set_pdate(self, date):
        """ set pdate """
        self._pdate = date
    
    pdate = property(get_pdate, set_pdate)
     
    def get_exitstate(self):
        """ Run or exit program? """
        return self._exitstate

    def set_exitstate(self, state):
        """ Set run-/exitstate """
        self._exitstate = state

    exitstate = property(get_exitstate, set_exitstate)
    
    def get_myconf(self):
        """ myconf """
        return self._myconf
    
    def set_myconf(self, version):
        """ set myconf """
        self._myconf = version
    
    myconf = property(get_myconf, set_myconf)

    def get_dbfile(self):
        """ dbfile """
        return self._dbfile
    
    def set_dbfile(self, version):
        """ set dbfile """
        self._dbfile = version
    
    dbfile = property(get_dbfile, set_dbfile)

    def get_input(self):
        """ input """
        return self._input
    
    def set_input(self, version):
        """ set input """
        self._input = version
    
    input = property(get_input, set_input)

    def __init__(self):
        """ Init of main class """
        self.set_pprog('valhalladb.py')
        self.set_pversion('0.01b')
        self.set_prelease('Thundergod')
        self.set_pdate('2010-02-28')
        self.set_exitstate(0)
        self.set_myconf(self.fConfFile())
        self.fConfig()
        self.fDataFile()
   
    def fConfFile(self):
        """ Get config file path. """
        return 'config/valhalladb/valhalladb.rc'

    def fDataFile(self):
        """ Get database file path. """
        return 'config/valhalladb/valhalladb.txt'

    def fConfig(self):
        """ Retrieve config file values """
        config = ConfigParser.RawConfigParser()
        config.read(self.get_myconf())

        dbfile = config.get('db', 'dbfile')
        self.set_dbfile(dbfile[1:-1])        

    def fUsage(self):
	    """ Print usage info and exit """
	    print self.get_pprog() + ''' : Cli application that can show you all characters of a Valhalla clan member.
    It uses valhalladb.txt as a database. Please make sure you have the latest version of this text-file.
    You can download it here: http://code.google.com/p/valhalladb/downloads/list
    It should be placed in the same location as the main application. 
	Options: 
	    -h : Displays this help message.
        --updtxt : Updates valhalladb.txt (backup for offline use).
                   This will be used when a connection to the server can not be made,
                   so technical problems will not prevent you from using the application.
        --offline : Force offline usage, so no connection will be made to the database. (Mainly used for testing purposes.)
	    --version : Displays version.
	    --python : Displays Python version.

    This application was brought to you by Rockwolf. Woohoo!'''

    def fRun(self):
        """ This is the main driver for the program. """
        # Test code.
        now = datetime.datetime.now()
        #print now.strftime("%Y-%m-%d %H:%M:%S") + ": running main thread ..."
        # Main method to call, goes here
        self.set_input('')
        inp = self.get_input()
        while inp != '/quit':
            if inp == '/help' or inp == '' or inp == '/updtxt':
                self.fGetInput()
                self.fParseInput(self.get_input())
                inp = self.get_input()
            else:
                self.fPlayerInfo()
                self.set_input('')
                inp = self.get_input()

    def fGetInput(self):
        """ Get user input. """
        print ''
        self.set_input(raw_input(self.get_pprog() + ' ' + self.get_pversion() + ' (/quit to close, /help for a list of commands)\nEnter name: ').strip().lower())

    def fParseInput(self, input):
        """ Parse user input. """
        if input == '/quit' : 
            sys.exit(0)
        elif input == '/help' :
            self.fHelp() 
        elif input == '/updtxt' :
            self.fUpdTxt() 
        else :
            if input[0:1] == '/' :
                self.fError('Error parsing input: ' + input)
                self.set_input('')
        
    def fPlayerInfo(self):
        """ Get player information from the db. """
        try:
            # if connection fails:
            db = open(self.get_dbfile())
            try:
                lines = db.readlines()
                lines.sort()
                fields = {}
                playerdata = {}
                i = 0
                for line in lines:
                    i = i + 1
                    if i >= 2: #skip comment lines in dbfile
                        if line.lower().find(self.get_input()) != -1:
                            player = [{}] # init/reset player list
                            #print 'LINE>>', line,
                            fields = line.split(';')
                            j = 0
                            for field in fields:
                                playerdata = field.split(':')
                                if j > 0: # don't add new entry on init, it will create an empty element too much
                                    player.append({'Name':'', 'Class':''})
                                player[j]['Name'] = playerdata[0].strip()
                                player[j]['Class'] = playerdata[1].strip()
                                j = j + 1
                                
                            #print 'PLAYER>>'
                            print ''
                            print player[0]['Name'] + '\'s characters'
                            print len(player[0]['Name'])*'-' + '-------------'
                            #for  in playerdetail(key,value):
                            for info in player:
                                print info['Name']  + ' : ' + info['Class']
            finally:
                db.close();
        except IOError as (errno, strerror):
            print "Error {0}: {1} at {2}.".format(errno, strerror, self.get_dbfile())

    def fUpdTxt(self):
        """ Get player information from db and put it in valhalladb.txt. """
        try:
            db = open(self.get_dbfile())
            try:
                lines = db.readlines()
                lines.sort()
                fields = {}
                playerdata = {}
                i = 0
                now = datetime.datetime.now()
                write: 
                    '# AUTOMATICALLY GENERATED by ' + self.get_pprog()
                    '#' + now.strftime("%Y-%m-%d %H:%M:%S")
                for line in lines:
                    i = i + 1
                    if i >= 2: #skip comment lines in dbfile
                        if line.lower().find(self.get_input()) != -1:
                            player = [{}] # init/reset player list
                            #print 'LINE>>', line,
                            fields = line.split(';')
                            j = 0
                            for field in fields:
                                playerdata = field.split(':')
                                if j > 0: # don't add new entry on init, it will create an empty element too much
                                    player.append({'Name':'', 'Class':''})
                                player[j]['Name'] = playerdata[0].strip()
                                player[j]['Class'] = playerdata[1].strip()
                                j = j + 1
                                
                            #print 'PLAYER>>'
                            print ''
                            print player[0]['Name'] + '\'s characters'
                            print len(player[0]['Name'])*'-' + '-------------'
                            #for  in playerdetail(key,value):
                            for info in player:
                                print info['Name']  + ' : ' + info['Class']
            finally:
                db.close();
        except IOError as (errno, strerror):
            print "Error {0}: {1} at {2}.".format(errno, strerror, self.get_dbfile())
    def fHelp(self):
        """ Errrr... I need help. """
        print 'General information'
        print '-------------------'
        print self.get_pprog() + ''' is a cli application that can show you all characters of a Valhalla clan member.
It uses valhalladb.txt as a database. Please make sure you have the latest version of this text-file.

You can download it here:
http://code.google.com/p/valhalladb/downloads/list

It should be placed in the same location as the main application. 
This application was brought to you by Rockwolf. Woohoo!
Is your name not in the list? Post your request on the forum at:
http://clan-valhalla.com
or contact Rockwolf in game.'''
        print ''
        print 'Available commands'
        print '------------------'
        print '/quit: Exits the program.'
        print '/help: You typed that already, to see this.'
        print '<name>: Searches for the name in the valhalla database.\n       Searches are not case sensitive.'
 
    def fError(self, strerror):
        """ Error. """
        print "Error: {0}.".format(strerror)
        
        
def fMain():
    """ Main driver, startup and cli options parsing. """
    # Gonna switch this to optparse later
    try:
        options, xarguments = getopt.getopt(sys.argv[1:], 'hr:a:', ['version', 'python'])
    except getopt.error,err:
        print 'Error: ' + str(err)
        sys.exit(1)

    cl = Valhalladb()

    for opt in options[:]:
        if opt[0] == '-h':
            cl.fUsage()
            cl.set_exitstate(1) # don't run the program after the optionparsing
    for opt in options[:]:
        if opt[0] == '--version':
            print cl.get_pprog() + ' version '+ cl.get_pversion() + ' (' + cl.get_pdate() + '), \'' + cl.get_prelease() + '\' release.'
            cl.set_exitstate(1)
            break
    for opt in options[:]:
        if opt[0] == '--python':
            print 'Python '+sys.version
            cl.set_exitstate(1)
            break

    if(cl.get_exitstate() == 1):
        sys.exit(0)
    else:
        cl.fRun() #run the main method for the program

if __name__ == "__main__":
    fMain()
